package repository

import (
	"context"
	"database/sql"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/redis/go-redis/v9"
	"time"
	"webook/internal/domain"
	"webook/internal/repository/cache"
	"webook/internal/repository/dao"
)

var ErrKeyNotExist = redis.Nil

type UserRepository struct {
	dao   *dao.UserDao
	cache *cache.UserCache
}

func (r *UserRepository) FindByEmail(c context.Context, email string) (domain.User, error) {
	u, err := r.dao.FindByEmail(c, email)
	if err != nil {
		return domain.User{}, err
	}
	return domain.User{
		Id:       u.Id,
		Email:    u.Email,
		Password: u.Password,
	}, nil
}

func NewUserRepository(dao *dao.UserDao, cache *cache.UserCache) *UserRepository {
	return &UserRepository{
		dao:   dao,
		cache: cache,
	}
}

func (r *UserRepository) CreateUser(ctx context.Context, u domain.User) error {
	return r.dao.Insert(ctx, dao.User{
		Email:    u.Email,
		Password: u.Password,
	})
}

func (r *UserRepository) GetUserProfileById(ctx context.Context, id int64) (domain.User, error) {
	u, err := r.cache.Get(ctx, id)
	if err == nil {
		// 必然是有数据

		return u, nil

	}

	ue, err := r.dao.GetUserProfileById(ctx, id)
	if err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			// 用户不存在，缓存空对象（设置较短的过期时间）
			emptyUser := domain.User{Id: -1} // 空对象标记
			go func() {
				err = r.cache.Set(ctx, emptyUser)
			}()
			return emptyUser, nil
		}
		return domain.User{}, err
	}
	u = domain.User{
		Email:    ue.Email,
		Password: ue.Password,
		Birthday: ue.Birthday.Time.Format("2006-01-02"),
		Profile:  ue.Profile,
		Nickname: ue.Nickname,
	}
	go func() {
		err = r.cache.Set(ctx, u)
		if err != nil {
			fmt.Println(err)
		}
	}()
	return u, err
}

func (r *UserRepository) UpdateUser(c *gin.Context, user domain.User) error {
	var birthday sql.NullTime
	if user.Birthday != "" {
		t, err := time.Parse("2006-01-02", user.Birthday)
		if err != nil {
			return err
		}
		birthday = sql.NullTime{
			Time:  t,
			Valid: true,
		}
	}

	return r.dao.UpdateUser(c, dao.User{
		Id:       user.Id,
		Email:    user.Email,
		Nickname: user.Nickname,
		Profile:  user.Profile,
		Birthday: birthday,
	})
}
